package com.atguigu.gmall.mq.listener;

import com.atguigu.gmall.mq.config.DeadLetterConfig;
import com.atguigu.gmall.mq.config.DelayedConfig;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;

/**
 * @author: 李旭
 * @create: 2021-09-11 14:22
 *
 *   消费者 监听消息
 **/
@SuppressWarnings("all")
@Component
public class ConsumerListener {

    //接收消息   手动应答  不再是自动应答
    @RabbitListener(queues = "queue1")
    public void receiverMessage(String msg, Channel channel, Message message){
        //直接将消息绑定形参上
        System.out.println("接收到的消息（直接）:" + msg);
        //从消息对象中获取消息
        System.out.println("接收到的消息（间接）:" +new String(message.getBody()));
        try {
            int i = 1/0; //by zero
            //手动应答
            //参数1：确认哪个消息  消息的唯一标记告诉我
            //参数2： 确认消息是否批量   true:批量  false:单个
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            //e.printStackTrace();
            //刚刚的消息  我给你一次重新来过的机会  只给一次机会 要求队列那边销毁你
            if(!message.getMessageProperties().isRedelivered()){
                //不是重来的 是刚来的  给一次机会
                //参数1：确认哪个消息  消息的唯一标记告诉我
                //参数2： 确认消息是否批量   true:批量  false:单个
                //参数3： 要求队列重新发送消息  true false
                try {
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(),
                            false,true);
                    System.out.println("第一次来 给个机会吧:" + msg);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }else{
                //是重新来过的 不给机会了 干掉它
                //参数2： 要求队列重新发送消息  true false
                try {
                    channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
                    System.out.println("第二次来 不给机会:" + msg);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                //写日志    没有无敌代码 只能无敌的人


            }

        }

    }
    //接收延迟消息（基于死信的）
    @RabbitListener(queues = DeadLetterConfig.queue_dead_2)
    public void receiverDeadLetterMessage(String msg, Channel channel, Message message){
        //直接将消息绑定形参上
        System.out.println("接收到的消息（直接）:" + msg + "：时间：" + new Date());
        try {
            //手动应答
            //参数1：确认哪个消息  消息的唯一标记告诉我
            //参数2： 确认消息是否批量   true:批量  false:单个
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            //e.printStackTrace();
            //刚刚的消息  我给你一次重新来过的机会  只给一次机会 要求队列那边销毁你
            if(!message.getMessageProperties().isRedelivered()){
                //不是重来的 是刚来的  给一次机会
                //参数1：确认哪个消息  消息的唯一标记告诉我
                //参数2： 确认消息是否批量   true:批量  false:单个
                //参数3： 要求队列重新发送消息  true false
                try {
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(),
                            false,true);
                    System.out.println("第一次来 给个机会吧:" + msg);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }else{
                //是重新来过的 不给机会了 干掉它
                //参数2： 要求队列重新发送消息  true false
                try {
                    channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
                    System.out.println("第二次来 不给机会:" + msg);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                //写日志    没有无敌代码 只能无敌的人


            }

        }

    }


    //基于插件的延迟消息
    @RabbitListener(queues = DelayedConfig.queue_delay_1)
    public void receiverDelayedMessage(String msg, Channel channel, Message message){
        //直接将消息绑定形参上
        System.out.println("接收到的消息（直接）:" + msg + "：时间：" + new Date());
        try {
            //手动应答
            //参数1：确认哪个消息  消息的唯一标记告诉我
            //参数2： 确认消息是否批量   true:批量  false:单个
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            //e.printStackTrace();
            //刚刚的消息  我给你一次重新来过的机会  只给一次机会 要求队列那边销毁你
            if(!message.getMessageProperties().isRedelivered()){
                //不是重来的 是刚来的  给一次机会
                //参数1：确认哪个消息  消息的唯一标记告诉我
                //参数2： 确认消息是否批量   true:批量  false:单个
                //参数3： 要求队列重新发送消息  true false
                try {
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(),
                            false,true);
                    System.out.println("第一次来 给个机会吧:" + msg);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }else{
                //是重新来过的 不给机会了 干掉它
                //参数2： 要求队列重新发送消息  true false
                try {
                    channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
                    System.out.println("第二次来 不给机会:" + msg);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                //写日志    没有无敌代码 只能无敌的人
            }

        }

    }

}
